package project.switchbutton.customview;

import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.support.annotation.Nullable;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.View;
import android.widget.Toast;

import project.switchbutton.R;

/**
 * Created by lgs on 2017/12/3.
 * 一个视图从创建到显示过程中的主要方法
 * 1、构造器实例化类
 * 2、测量-measure(int, int )-->onMeasure();
 * 如果当前View是一个ViewGroup，还有义务测量孩子
 * 孩子有建议权
 * 3、指定位置-layout()-->onLayout();
 * 指定控件的位置，一般View不用写这个方法，ViewGroup的时候才需要，
 * 一般View不需要重写该方法
 * 4、绘制视图--draw()--onDraw(canvas)
 * 根据上面两个参数，进入绘制
 */

public class ToggleButton extends View implements View.OnClickListener {

    private static final String TAG = ToggleButton.class.getSimpleName();
    private Bitmap mBgBitmap;   //背景
    private Bitmap mSlideBitmap;    //开关图
    private Paint mPaint;   //画笔

    private boolean isOpen; //是否开启

    /**
     * true:点击事件生效，滑动事件失效
     * false:点击事件失效，滑动事件生效
     */
    private boolean isEnableClick = true;

    private float lastX; //事件处理中的原始值

    //距离左边最大距离
    private int slideLeftMax;

    private int slideLeft;

    private float startX;


    /**
     * 布局文件使用该构造器实例该类，如果没有就崩溃
     */
    public ToggleButton(Context context, @Nullable AttributeSet attrs) {
        super(context, attrs);
        initView();
    }

    //初始化
    private void initView() {
        mPaint = new Paint();
        mPaint.setAntiAlias(true);  //设置抗锯齿
        mBgBitmap = BitmapFactory.decodeResource(getResources(), R.drawable.switch_background);
        mSlideBitmap = BitmapFactory.decodeResource(getResources(), R.drawable.slide_button);
        setOnClickListener(this);
    }

    //测量视图
    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        setMeasuredDimension(mBgBitmap.getWidth(), mBgBitmap.getHeight());
        slideLeftMax = mBgBitmap.getWidth() - mSlideBitmap.getWidth();
        //                super.onMeasure(widthMeasureSpec, heightMeasureSpec);
    }

    //绘制视图
    @Override
    protected void onDraw(Canvas canvas) {
        canvas.drawBitmap(mBgBitmap, 0, 0, mPaint);
        canvas.drawBitmap(mSlideBitmap, slideLeft, 0, mPaint);
    }

    @Override
    public void onClick(View v) {
        if (isEnableClick) {
            isOpen = !isOpen;
            flush();
        }
    }

    private void flush() {
        if (isOpen) {
            slideLeft = slideLeftMax;
            Toast.makeText(getContext(), "开", Toast.LENGTH_SHORT).show();
        } else {
            slideLeft = 0;
            Toast.makeText(getContext(), "关", Toast.LENGTH_SHORT).show();
        }
        invalidate();   //会导致onDraw()方法执行
    }


    @Override
    public boolean onTouchEvent(MotionEvent event) {
        super.onTouchEvent(event);  //调用父类方法，进行事件回传
        int action = event.getAction();
        switch (action) {
            case MotionEvent.ACTION_DOWN:
                //记录按下的位置
                lastX = startX = event.getX();
                //一按下就认为是点击
                isEnableClick = true;
                break;
            case MotionEvent.ACTION_MOVE:
                //记录结束位置
                float endX = event.getX();

                //记录事件处理中的位置
                if (Math.abs(endX - lastX) > 5) {
                    //滑动
                    isEnableClick = false;
                }
                //计算偏移量
                float distance = endX - startX;

                //
                slideLeft += distance;
                //屏蔽非法值
                if (slideLeft < 0) {
                    slideLeft = 0;
                } else if (slideLeft > slideLeftMax) {
                    slideLeft = slideLeftMax;
                }
                //刷新
                invalidate();

                //数据还原
                startX = event.getX();
                break;
            case MotionEvent.ACTION_UP:
                if (!isEnableClick) {
                    isOpen = slideLeft >= slideLeftMax / 2;
                    flush();
                }
                break;
        }
        return true;
    }
}
